#include "fnetprotocol.h"
#include <QDebug>

FNetProtocol::FNetProtocol()
    :u8PacketHeaderA(0xAA),
     u8PacketHeaderB(0x55),
     m_s32CheckErr(0)
{
    ClearData();
    m_s32CheckErr = 0;
}

FNetProtocol::~FNetProtocol()
{
    ClearData();
    m_s32CheckErr = 0;
}

quint8 FNetProtocol::CheckSum(const QByteArray &bufBody)
{
    int iCheckSum = 0;

    for(int i = 0; i < bufBody.length(); ++i)
    {
        iCheckSum += (quint8)bufBody.at(i);
    }

    // 取低字节作为校验和
    return (iCheckSum & 0xFF);
}

//  包头 （2byte）  + 长度 （4 byte） + Data （n byte） + 校验和 (1 byte)
qint32 FNetProtocol::NetPackFill(const QByteArray &byteData, QByteArray &bytePack/*, BOOL bCompress*/)
{
    if(byteData.size()<=0)
    {
        qWarning() << "NetPackFill byteData len = 0!";
        return 0;
    }
    //是否对数据进行压缩
//    if( TRUE == bCompress )
//    {
//        byteData = qCompress(byteData);
//    }

    qint32 s32DataLen = byteData.size();
    // 协议包头 2 byte
    bytePack.append(u8PacketHeaderA);
    bytePack.append(u8PacketHeaderB);

   // 长度 32bit 4 byte
    bytePack.append((uchar)  (0x000000ff & s32DataLen));
    bytePack.append((uchar) ((0x0000ff00 & s32DataLen) >> 8));
    bytePack.append((uchar) ((0x00ff0000 & s32DataLen) >> 16));
    bytePack.append((uchar) ((0xff000000 & s32DataLen) >> 24));
    // 协议包体
    bytePack.append(byteData);

    // 校验和
    quint8 u8CheckSum = CheckSum(byteData);

    // 组包
    bytePack.append(u8CheckSum);

//    qDebug() << "NetPackFill SEND:" << bytePack.size();
    //DbgHex8(bytePack);

    return bytePack.size();
}
//清除缓存数据，用于端口重连。或者解包异常时清除
bool FNetProtocol::ClearData()
{
    m_curPackArr.clear();          //获取当前数据包缓冲数据
    m_bPackGotFlagA = false;       //是否获取到包头A
    m_bPackGotFlagB = false;       //是否获取到包头B
    m_s32CurPackLen = 0;           //当前包解析出来长度

    return true;
}

qint32 FNetProtocol::NetUnPack(QByteArray &byteBuf)
{
    qint32 iActPack = 0;

    if(byteBuf.size() <= 0)
    {
        return false;
    }

    for (qint32 i = 0; i < byteBuf.size(); ++i)
    {
        quint8 u8TmpData = byteBuf.at(i);

        if(false == m_bPackGotFlagA || false == m_bPackGotFlagB)
        {//找帧头
            if(false == m_bPackGotFlagA
                && false == m_bPackGotFlagB
                && u8PacketHeaderA == u8TmpData) //<8找到头flag1
            {
                m_curPackArr.clear();
                m_s32CurPackLen=0;//当前包解析出来长度
                m_curPackArr.append(u8TmpData);
                m_bPackGotFlagA=true;
                m_bPackGotFlagB=false;
                continue;
            }
            if((u8PacketHeaderA==(quint8)m_curPackArr[0])
                &&(true == m_bPackGotFlagA &&  false == m_bPackGotFlagB)
                &&(u8PacketHeaderB==u8TmpData)) //找到头flag2
            {
                m_curPackArr.append(u8TmpData);
                m_s32CurPackLen=0;
                m_bPackGotFlagA=true;
                m_bPackGotFlagB=true;
                continue;
            }

        }
        else
        {
            //  包头 （2byte）  + 长度 （4 byte） + Data （n byte） + 校验和 (1 byte)
            m_curPackArr.append(u8TmpData);
            if(m_curPackArr.size() >=	(int)sizeof(NETDATA_PACK_STRU))
            {
                if(0 == m_s32CurPackLen)//获取包长
                {

                    m_s32CurPackLen = (quint8)m_curPackArr[2] & 0x000000FF;
                    m_s32CurPackLen |= (((quint8)m_curPackArr[3] << 8) & 0x0000FF00);
                    m_s32CurPackLen |= (((quint8)m_curPackArr[4] << 16) & 0x00FF0000);
                    m_s32CurPackLen |= (((quint8)m_curPackArr[5] << 24) & 0xFF000000);

                    m_s32CurPackLen +=(2+4+1); //注意需要加上包头 （2byte） + + 长度 （4 byte）+ 校验和 (1 byte)
                    //qDebug()<<"PackLenth "<<m_s32CurPackLen<<(INT8U)m_curPackArr[2]<<(INT8U)m_curPackArr[3]<<(INT8U)m_curPackArr[4]<<(INT8U)m_curPackArr[5];
                }

                if(m_curPackArr.size() == m_s32CurPackLen) //获取整个数据包长
                {
                    //qDebug()<<m_curPackArr.size()<<m_curPackArr.toHex();
                    quint8 u8CheckSum = m_curPackArr[m_s32CurPackLen-1];
                    QByteArray byteData = m_curPackArr.mid(6, m_s32CurPackLen-7);
                    //printf("crcRslt %d \n",crcRslt);
                    if(u8CheckSum == CheckSum(byteData))
                    {
                        //packCnt = packCnt - PackLenth;//解析是否完整
                        //printf( "VcmUnFrameProc   packCnt  = %ld  Get ------ \n ",packCnt);
                        iActPack ++;
                        RecvPackData(byteData);
                        //printf("Get pack End\n");
                    }
                    else
                    {
                        m_s32CheckErr++;
                        printf("check sum error 2 %d %x!\n",m_s32CheckErr,u8CheckSum);
                    }

                    ClearData();
                }
            }
        }

    }
    return iActPack;
}

int FNetProtocol::DbgHex8(QByteArray &byteData)
{
    int i;
    for(i=0; i<byteData.size(); i++)
    {
        if(i%10==0)
        {
            printf("\n");
        }
        printf("0x%02x,",byteData.at(i));
    }
    printf("\n");
    return byteData.size();
}
